const proto = require('./pb/awesome')

const WebSocket = require('ws');
const server = new WebSocket.Server({ port: 8081 });

/*
const data = proto.awesome.AwesomeMessage.encode({ name: 'Jack', age: 12 }).finish();
console.log(`encode ${data}`);

const message = proto.awesome.AwesomeMessage.decode(data);
console.log(`decode ${JSON.stringify(message)}`);
*/

server.on('connection', (ws) => {
    console.log("New client connected");

    ws.on('message', (data) => {
        // console.log(`Received: ${data}`);
        //虽然客户端那边传的时候是ArrayBuffer类型，但是经过调试到这里data类型为buffer，需要转换为ArrayBuffer
        var arrayBuf = toArrayBuffer(data);
        var r = unSerialize(arrayBuf);
        if (r.msgId === 10001) {
            console.log(`Received Msg: ${JSON.stringify(r)}`);
            // 给客户端发送protobuf编码消息
            const data = proto.awesome.AwesomeMessage.encode({ name: 'Nico', age: 16 }).finish();
            ws.send(serialize(10001, data));
        }
    });

    ws.on('close', () => {
        console.log('Client disconnected');
    });

    // ws.send('welcome to  WebSocket server!');
});

// 反序列化
function unSerialize(arrayBuf) {
    var dv = new DataView(arrayBuf);
    //获得消息号
    var id = dv.getInt32(0); //TODO:大小端问题。dv.getInt32(0,true);
    //获得消息体
    var body = new Uint8Array(arrayBuf, 4);
    var result = null;
    switch (id) {
        case 10001:
            result = proto.awesome.AwesomeMessage.decode(body);
            break;
    }
    // console.log("rcvMsg: " + id + ",  " + JSON.stringify(result));
    return { msgId: id, data: result };
}

// 序列化
function serialize(msgId, bodyArray) {
    var totalLen = 4;
    totalLen += (bodyArray.length * 1); //Uint8为一个字节
    //写入消息号
    var buf = new ArrayBuffer(totalLen);
    var dataView = new DataView(buf);
    dataView.setInt32(0, msgId);
    var offset = 4;
    //写入消息体
    for (var i = 0; i < bodyArray.length; i++) {
        var element = bodyArray[i];
        dataView.setUint8(offset, element);
        offset += 1;
    }
    return dataView.buffer;
}

//Buffer转ArrayBuffer
function toArrayBuffer(buf) {
    var ab = new ArrayBuffer(buf.length);
    var view = new Uint8Array(ab);
    for (var i = 0; i < buf.length; ++i) {
        view[i] = buf[i];
    }
    return ab;
}

//ArrayBuffer转Buffer
function toBuffer(ab) {
    var buf = new Buffer(ab.byteLength);
    var view = new Uint8Array(ab);
    for (var i = 0; i < buf.length; ++i) {
        buf[i] = view[i];
    }
    return buf;
}

console.log(`WebSocket server is running on ws://localhost:8081`);